/**
 *
 * Copyright Pact Lab of H.I.T.
 *
 * Designed and Implemented by Grid Researching Group, 
 * Pact Lab, Harbin
 * 
 * This Project is part of the national 973 Project:
 * Internet Based Virtual Computing Environment
 *
 * http://pact518.hit.edu.cn
 * 
 * Author:       Meteor <meteorlxk@gmail.com> 
 * Copyright:    pact518 
 * Version:      1.0
 * Created:      2009-5-5 
 * LastModified: 2009-5-5
 */
package edu.hit.pact.pgse.bean;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

import edu.hit.pact.pgse.crawler.web.UrlUnit;
import edu.hit.pact.pgse.util.Utilities;

/**
 * @author meteorlxk
 * 
 */
public class TaskPieceProperty implements Serializable {

	private static final long serialVersionUID = -2653171827759520299L;

	public static final int ALIVE = 1;
	public static final int FINISHED = 2;
	public static final int FINISHED_AND_REPORTED = 3;
	public static final int CANCELED = 4;

	private final TaskPiece piece;
	private AtomicInteger status;
	private AtomicInteger semaphore;
	private PriorityBlockingQueue<UrlUnit> cleanUrlQueue;// use to keep the
															// order of url,
															// according to the
															// number of
															// backlinks
	private ConcurrentHashMap<String, UrlUnit> urlUnitMap;// use to trace the
															// urlUnit and
															// modify the
															// backlinks
	private long startTime;
	private AtomicInteger succeededPageNumber;
	private AtomicInteger failedPageNumber;

	public TaskPieceProperty(TaskPiece piece) {
		this.piece = piece;

		this.status = new AtomicInteger(ALIVE);

		this.semaphore = new AtomicInteger(0);

		this.cleanUrlQueue = new PriorityBlockingQueue<UrlUnit>();
		this.urlUnitMap = new ConcurrentHashMap<String, UrlUnit>();

		this.startTime = Utilities.getDateInMillisecond();
		this.succeededPageNumber = new AtomicInteger(0);
		this.failedPageNumber = new AtomicInteger(0);
	}

	public ConcurrentHashMap<String, UrlUnit> getUrlUnitMap() {
		return urlUnitMap;
	}

	public void setUrlUnitMap(ConcurrentHashMap<String, UrlUnit> urlUnitMap) {
		this.urlUnitMap = urlUnitMap;
	}

	/**
	 * @return the status
	 */
	public int getStatus() {
		return status.get();
	}

	/**
	 * @param status
	 *            the status to set
	 */
	public void setStatus(int status) {
		this.status.set(status);
	}

	public long getStartTime() {
		return startTime;
	}

	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}

	public PriorityBlockingQueue<UrlUnit> getCleanUrlQueue() {
		return cleanUrlQueue;
	}

	public void incrementSemaphore() {
		semaphore.incrementAndGet();
	}

	public void decrementSemaphore() {
		semaphore.decrementAndGet();
	}

	public int getSemaphore() {
		return semaphore.get();
	}

	public void incrementSucceededPageNum() {
		succeededPageNumber.incrementAndGet();
	}

	public void incrementFailedPageNum() {
		failedPageNumber.incrementAndGet();
	}

	/**
	 * @return the piece
	 */
	public TaskPiece getPiece() {
		return piece;
	}

	//	
	// public void setCleanUrlQueueRemain(AtomicInteger num){
	// this.cleanUrlQueueRemain = num;
	// }

	/**
	 * @return the succeededPageNumber
	 */
	public int getSucceededPageNum() {
		return succeededPageNumber.get();
	}

	public TaskPieceStatistics toStatistics() {
		long finishedTime = Utilities.getDateInMillisecond();

		Collection<UrlUnit> collection = urlUnitMap.values();
		Object[] array = collection.toArray();
		
		//when sort, it is in quality control
		//when not sort, it is not in quality control
		Arrays.sort(array);
		
		int backlinkSum = 0;
		for (int i=0; i<piece.maxPageNum&& i<urlUnitMap.size(); i++){
			UrlUnit urlUnit = (UrlUnit)array[i];
//			System.out.println(urlUnit.getLink() +"  "+ urlUnit.getBacklinks());
			backlinkSum += urlUnit.getBacklinks();
		}
		return new TaskPieceStatistics(piece.getId(), piece.getHomePage(),
				startTime, finishedTime, succeededPageNumber.get(),
				failedPageNumber.get(), (double)backlinkSum/piece.maxPageNum);
	}

	@Override
	public String toString() {
		return "TaskPieceProperty [failedPageNumber=" + failedPageNumber
				+ ", piece=" + piece + ", startTime=" + startTime + ", status="
				+ status + ", succeededPageNumber=" + succeededPageNumber + "]";
	}

	// public String showBacklinks(){
	// StringBuffer sb = new StringBuffer();
	//		
	// for
	// }

}
